---
title: Setting up Storybook Composition with Nx
description: Learn how to set up Storybook composition in your Nx workspace to combine multiple Storybook instances into one unified interface.
sidebar:
  label: Setting up Storybook Composition with Nx
filter: 'type:Guides'
---

[Storybook Composition](https://storybook.js.org/docs/sharing/storybook-composition) allows you to embed multiple Storybook instances in one Storybook, giving you a unified view of all your components across different projects and frameworks.

## What is Storybook Composition?

Storybook Composition is a way to combine multiple Storybook instances into a single interface. This is particularly useful when:

- You have multiple projects using different frameworks (React, Angular, Vue, etc.)
- You want to create a central hub for all your design system components
- You need to showcase components from different teams or repositories

## Setting up the main Storybook

First, you need a main Storybook instance that will serve as the host for other Storybooks.

### Generate a host library

```shell
nx g @nx/react:library storybook-host --bundler=none --unitTestRunner=none
```

### Configure Storybook for the host

```shell
nx g @nx/storybook:configuration storybook-host --uiFramework=@storybook/react-vite
```

## Setting up composed Storybooks

Each Storybook that you want to compose needs to be accessible via a URL. This means you need to:

1. Ensure each composed Storybook runs on a different port
2. Build and deploy each composed Storybook to a URL

### Configure ports for composed Storybooks

Update the `project.json` files of your composed Storybooks to use different ports:

```json
// libs/ui-lib-1/project.json
{
  "targets": {
    "storybook": {
      "options": {
        "port": 4401
      }
    }
  }
}
```

```json
// libs/ui-lib-2/project.json
{
  "targets": {
    "storybook": {
      "options": {
        "port": 4402
      }
    }
  }
}
```

## Configure the main Storybook

In your main Storybook's configuration file, add references to the composed Storybooks:

```typescript
// libs/storybook-host/.storybook/main.ts
import type { StorybookConfig } from '@storybook/react-vite';

const config: StorybookConfig = {
  stories: ['../src/lib/**/*.stories.@(js|jsx|ts|tsx|mdx)'],
  addons: ['@storybook/addon-essentials'],
  framework: {
    name: '@storybook/react-vite',
    options: {},
  },
  refs: {
    'ui-lib-1': {
      title: 'UI Library 1',
      url: 'http://localhost:4401',
    },
    'ui-lib-2': {
      title: 'UI Library 2',
      url: 'http://localhost:4402',
    },
  },
};

export default config;
```

## Running the composed Storybooks

To see your composed Storybooks in action:

1. Start each composed Storybook on its designated port:

```shell
nx storybook ui-lib-1
nx storybook ui-lib-2
```

2. Start the main Storybook:

```shell
nx storybook storybook-host
```

Now when you open the main Storybook, you'll see entries in the sidebar for each composed Storybook.

## Deploying composed Storybooks

For production use, you'll need to:

1. Build and deploy each composed Storybook to a URL
2. Update the `refs` in your main Storybook configuration to point to these deployed URLs

```typescript
// libs/storybook-host/.storybook/main.ts
const config: StorybookConfig = {
  // ... other config
  refs: {
    'ui-lib-1': {
      title: 'UI Library 1',
      url: 'https://ui-lib-1.storybook.company.com',
    },
    'ui-lib-2': {
      title: 'UI Library 2',
      url: 'https://ui-lib-2.storybook.company.com',
    },
  },
};
```

## Benefits and limitations

### Benefits

- Unified interface for multiple Storybooks
- Support for different frameworks in the same view
- Centralized documentation hub

### Limitations

- Each composed Storybook needs to be built and deployed separately
- Network latency can affect loading times
- More complex deployment setup

For detailed implementation examples, see the guides on [publishing strategies](/docs/technologies/test-tools/storybook/guides/one-storybook-with-composition).
